const REGEX: RegExp = /(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})/;
/**
 * 格式化时间戳为指定格式的时间字符串
 * @param {number} val 时间戳（秒）
 * @param {string} [format] 格式化字符串，默认 'yyyy-MM-dd hh:mm:ss'
 * @return {string} 格式化后的时间字符串，若 val 无效则返回 '--'
 *
 * 示例：
 * formatTime(1718000000) // '2024-06-10 16:53:20'
 * formatTime(1718000000, 'yyyy/MM/dd hh:mm') // '2024/06/10 16:53'
 */
export const formatTime = (val: number, format?: string): string => {
  format = format || "yyyy-MM-dd hh:mm:ss";
  if (val) {
    let date = new Date(val * 1000);
    date.setHours(date.getHours() + 8);
    let iterator = date.toISOString().match(REGEX) || [];
    const yy = iterator[1] || "";
    const MM = iterator[2] || "";
    const dd = iterator[3] || "";
    const hh = iterator[4] || "";
    const mm = iterator[5] || "";
    const ss = iterator[6] || "";
    if (format) {
      return format
        .replace("yyyy", yy)
        .replace("yy", yy.slice(2))
        .replace("MM", MM)
        .replace("dd", dd)
        .replace("hh", hh)
        .replace("mm", mm)
        .replace("ss", ss);
    } else {
      return [yy, MM, dd].join("-") + " " + [hh, mm, ss].join(":");
    }
  } else {
    return "--";
  }
};

/**
 * 获取指定年份的年初和年末的时间戳（秒）
 * @param {number} [year=new Date().getFullYear()] 年份，默认当前年份
 * @return {{statrTimeStamp:number,endTimeStamp:number}}
 *         statrTimeStamp: 该年1月1日0点的时间戳（秒）
 *         endTimeStamp: 该年12月31日23:59:59的时间戳（秒）
 *
 * 示例：
 * yearTime() // 当前年
 * yearTime(2023) // 2023年
 */
export const yearTime = (
  year: number = new Date().getFullYear()
): { statrTimeStamp: number; endTimeStamp: number } => {
  return {
    statrTimeStamp: new Date(year, 0, 1).getTime() / 1000,
    endTimeStamp: new Date(year, 11, 31).getTime() / 1000 + 86399,
  };
};
/**
 * 根据指定年和月获取该月的开始时间和结束时间戳（秒）
 * @param {number} [year=new Date().getFullYear()] 年份，默认当前年
 * @param {number} [month=new Date().getMonth()+1] 月份（1-12），默认当前月
 * @return {{statrTimeStamp:number,endTimeStamp:number}}
 *         statrTimeStamp: 该月1日0点的时间戳（秒）
 *         endTimeStamp: 该月最后一天23:59:59的时间戳（秒）
 *
 * 示例：
 * monthTime() // 当前月
 * monthTime(2023, 5) // 2023年5月
 */
export const monthTime = (
  year: number = new Date().getFullYear(),
  month: number = new Date().getMonth() + 1
): { statrTimeStamp: number; endTimeStamp: number } => {
  return {
    statrTimeStamp: new Date(year, month - 1, 1).getTime() / 1000,
    endTimeStamp: new Date(year, month, 0).getTime() / 1000 + 86399,
  };
};
/**
 * 获取指定日期的开始和结束的时间戳（秒）
 * @param {number} [val=new Date().getTime()] 时间戳（毫秒），默认当前时间
 * @return {{statrTimeStamp:number,endTimeStamp:number}} 当天0点和23:59:59的时间戳
 *
 * 示例：
 * dayTime() // 今天的起止时间戳
 * dayTime(new Date('2024-06-10').getTime()) // 2024-06-10 的起止时间戳
 */
export const dayTime = (
  val: number = new Date().getTime()
): { statrTimeStamp: number; endTimeStamp: number } => {
  return {
    statrTimeStamp: parseInt(
      (new Date(new Date(val).toLocaleDateString()).getTime() / 1000).toString()
    ), //
    endTimeStamp: parseInt(
      (
        (new Date(new Date(val).toLocaleDateString()).getTime() +
          24 * 60 * 60 * 1000 -
          1) /
        1000
      ).toString()
    ),
  };
};
/**
 * 获得指定时间所在季度的开始和结束的时间戳（秒）
 * @param {number} [val=new Date().getTime()] 时间戳（毫秒），默认当前时间
 * @return {{statrTimeStamp:number,endTimeStamp:number}} 季度初和季度末的时间戳
 *
 * 示例：
 * getQuarterStartDate() // 当前季度
 * getQuarterStartDate(new Date('2024-06-10').getTime()) // 2024年第二季度
 */
export const getQuarterStartDate = (
  val: number = new Date().getTime()
): { statrTimeStamp: number; endTimeStamp: number } => {
  let data = new Date(new Date(val).toLocaleDateString());
  let quarterStartDate = new Date(
    data.getFullYear(),
    getQuarterStartMonth(val),
    1
  );
  let quarterEndMonth = getQuarterStartMonth(val) + 2;
  let quarterEndDate = new Date(
    data.getFullYear(),
    quarterEndMonth,
    getMonthDays(val, quarterEndMonth + 1)
  );
  return {
    statrTimeStamp: parseInt((quarterStartDate.getTime() / 1000).toString()), //
    endTimeStamp: parseInt(
      (quarterEndDate.getTime() / 1000 + 86399).toString()
    ),
  };
};
/**
 * 获得本季度的开端月份
 * @param {number} [val=new Date().getTime()] 时间戳（毫秒），默认当前时间
 * @return {number} 本季度的开端月份（0-11）
 */
export const getQuarterStartMonth = (
  val: number = new Date().getTime()
): number => {
  const nowMonth: number = new Date(val).getMonth(); // 0~11
  if (nowMonth < 3) {
    return 0;
  } else if (nowMonth < 6) {
    return 3;
  } else if (nowMonth < 9) {
    return 6;
  } else {
    return 9;
  }
};

/**
 * 获得某月的天数
 * @param {number} [val=new Date().getTime()] 时间戳（毫秒），默认当前时间
 * @param {number} [myMonth] 指定月份（1-12），可选。不传则取val对应的月份
 * @return {number} 天数
 *
 * 示例：
 * getMonthDays() // 当前月天数
 * getMonthDays(new Date('2024-02-01').getTime()) // 2024年2月天数
 * getMonthDays(new Date('2024-01-01').getTime(), 2) // 2024年2月天数
 */
export const getMonthDays = (
  val: number = new Date().getTime(),
  myMonth?: number
): number => {
  const d = new Date(val);
  if (myMonth !== undefined) {
    d.setMonth(myMonth - 1);
  }
  const monthStartDate = new Date(d.getFullYear(), d.getMonth(), 1).getTime();
  const monthEndDate = new Date(d.getFullYear(), d.getMonth() + 1, 1).getTime();
  return (monthEndDate - monthStartDate) / (1000 * 60 * 60 * 24);
};

/**
 * 获取N天后或者N天前的时间戳（当天0点和23:59:59）
 * @param {number} [val=new Date().getTime()] 时间戳（毫秒），默认当前时间
 * @param {number} [AddDayCount=0] 天数，正数为N天后，负数为N天前，默认0
 * @return {{statrTimeStamp:number,endTimeStamp:number}} 包含开始时间戳和结束时间戳的对象
 *
 * 示例：
 * getDateOldAndNewTime() // 今天的起止时间戳
 * getDateOldAndNewTime(new Date('2024-06-10').getTime(), 3) // 2024-06-13 的起止时间戳
 * getDateOldAndNewTime(new Date('2024-06-10').getTime(), -2) // 2024-06-08 的起止时间戳
 */
export const getDateOldAndNewTime = (
  val: number = new Date().getTime(),
  AddDayCount: number = 0
): { statrTimeStamp: number; endTimeStamp: number } => {
  const dd = new Date(val);
  dd.setDate(dd.getDate() + AddDayCount);
  const y = dd.getFullYear();
  //获取当前月份的日期，不足10补0
  const m =
    dd.getMonth() + 1 < 10 ? "0" + (dd.getMonth() + 1) : dd.getMonth() + 1;
  //获取当前几号，不足10补0
  const d = dd.getDate() < 10 ? "0" + dd.getDate() : dd.getDate();
  return dayTime(new Date(y + "-" + m + "-" + d).getTime());
};

/**
 * 获取本月剩余的天数
 * @param {number} [val=new Date().getTime()] 时间戳（毫秒），默认当前时间
 * @return {number} 剩余的天数
 *
 * 示例：
 * surplusDay() // 本月剩余天数
 * surplusDay(new Date('2024-06-10').getTime()) // 2024年6月10日所在月的剩余天数
 */
export const surplusDay = (val: number = new Date().getTime()): number => {
  const today = new Date(val);
  const now = today.getDate();
  const month: number = today.getMonth();
  let year = today.getFullYear();
  if (year < 2000) year += 1900;
  const monarr = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
  if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) monarr[1] = 29;
  return (monarr[month] as number) - now;
};

// /**
//  * 获取时间戳所在周的开始时间和结束时间
//  * @param {number} [val=new Date().getTime()] 时间戳（毫秒），默认当前时间
//  * @returns {{statrTimeStamp: number, endTimeStamp: number, nowWeek: number}}
//  *          statrTimeStamp: 本周一0点的时间戳（秒）
//  *          endTimeStamp: 本周日23:59:59的时间戳（秒）
//  *          nowWeek: 当月第几周
//  *
//  * 示例：
//  * getNowDateAndNowWeek() // 本周的起止时间戳和第几周
//  * getNowDateAndNowWeek(new Date('2024-06-10').getTime()) // 2024-06-10 所在周的起止时间戳和第几周
//  */
// export const getNowDateAndNowWeek = (val: number = new Date().getTime()): { statrTimeStamp: number, endTimeStamp: number, nowWeek: number } => {
//     var data = new Date(new Date(val).toLocaleDateString());
//     var weekStartDate = new Date(data.getFullYear(), data.getMonth(), data.getDate() - (data.getDay() == 0 ? 6 : data.getDay() - 1)); //从周一开始  周日开始把-1去掉
//     var weekEndDate = new Date(data.getFullYear(), data.getMonth(), data.getDate() + (6 - (data.getDay() == 0 ? 6 : data.getDay() - 1)));//从周一开始  周日开始把-1去掉
//     return {
//         nowWeek: getMonthWeek(val), //第几周
//         statrTimeStamp: weekStartDate.getTime() / 1000,//周一日期时间戳
//         endTimeStamp: (weekEndDate.getTime() / 1000) + 86399,//周日日期时间戳
//     };
// }

// /**
//  * 获取当月的第几周
//  * @param {number} [val=new Date().getTime()] 时间戳（毫秒），默认当前时间
//  * @return {number} 第几周
//  */
// export const getMonthWeek = (val: number = new Date().getTime()): number => {
//     var date = new Date(new Date(val).toLocaleDateString());
//     var w = date.getDay()
//     var d = date.getDate();
//     return Math.ceil(
//         (d + 6 - w) / 7
//     );
// }

/**
 * 获取时间戳所在周的开始时间和结束时间
 * @param {number} [val=new Date().getTime()] 时间戳（毫秒），默认当前时间
 * @returns {{statrTimeStamp: number, endTimeStamp: number, nowWeek: number}}
 *          statrTimeStamp: 本周一0点的时间戳（秒）
 *          endTimeStamp: 本周日23:59:59的时间戳（秒）
 *          nowWeek: 当月第几周
 *
 * 示例：
 * getNowDateAndNowWeek() // 本周的起止时间戳和第几周
 * getNowDateAndNowWeek(new Date('2024-06-10').getTime()) // 2024-06-10 所在周的起止时间戳和第几周
 */
export const getNowDateAndNowWeek = (
  val: number = new Date().getTime()
): { statrTimeStamp: number; endTimeStamp: number; nowWeek: number } => {
  const date = new Date(val);
  // 以周一为一周的开始
  const day = date.getDay() === 0 ? 7 : date.getDay(); // 周日为7
  // 本周一
  const monday = new Date(
    date.getFullYear(),
    date.getMonth(),
    date.getDate() - day + 1
  );
  // 本周日
  const sunday = new Date(
    date.getFullYear(),
    date.getMonth(),
    date.getDate() - day + 7
  );
  return {
    nowWeek: getMonthWeek(val),
    statrTimeStamp: Math.floor(monday.getTime() / 1000),
    endTimeStamp: Math.floor(sunday.getTime() / 1000) + 86399,
  };
};

/**
 * 获取当月的第几周（以周一为一周的开始）
 * @param {number} [val=new Date().getTime()] 时间戳（毫秒），默认当前时间
 * @return {number} 第几周
 */
export const getMonthWeek = (val: number = new Date().getTime()): number => {
  const date = new Date(val);
  const day = date.getDate();
  // 本月1号
  const firstDay = new Date(date.getFullYear(), date.getMonth(), 1);
  // 1号是周几（周日为7）
  const firstDayWeek = firstDay.getDay() === 0 ? 7 : firstDay.getDay();
  // 计算当前是第几周
  return Math.ceil((day + firstDayWeek - 1) / 7);
};

/**
 * 获取指定时间的年月字符串
 * @param {number} [val=new Date().getTime()] 时间戳（毫秒），默认当前时间
 * @param {string} [identifier='/'] 分隔符，默认'/'
 * @return {string} 形如 '2024/06' 的字符串
 */
export const getMonth = (
  val: number = new Date().getTime(),
  identifier = "/"
) => {
  return `${new Date(val).getFullYear()}${identifier}${
    new Date(val).getMonth() < 10
      ? "0" + (new Date(val).getMonth() + 1)
      : new Date(val).getMonth() + 1
  }`;
};

/**
 * 将秒数格式化为“天 时:分:秒”字符串
 * @param {number} seconds 秒数
 * @return {string} 格式化后的字符串，如 "1d 02:03:04" 或 "00:03:04"
 */
export const secondsToHms = (seconds: number): string => {
  if (seconds === undefined || seconds === null || isNaN(seconds)) return "--";
  let sec = seconds; // 不修改原始参数
  const d = Math.floor(sec / 86400);
  sec %= 86400;
  const h = String(Math.floor(sec / 3600)).padStart(2, "0");
  const m = String(Math.floor((sec % 3600) / 60)).padStart(2, "0");
  const s = String(sec % 60).padStart(2, "0");
  return (d > 0 ? `${d}d ` : "") + `${h}时${m}分${s}秒`;
};

/**
 * 获取两个日期之间的所有日期字符串（格式化）
 * @param {string} start 开始日期（如 '2024-07-01'）
 * @param {string} end 结束日期（如 '2024-07-05'）
 * @returns {string[]} 日期字符串数组，格式为 'yyyy-MM-dd hh:mm:ss'
 *
 * 示例：
 * getDaysBetween('2024-07-01', '2024-07-03')
 * // 返回: ['2024-07-01 00:00:00', '2024-07-02 00:00:00', '2024-07-03 00:00:00']
 */
export const getDaysBetween = (start: string, end: string): string[] => {
  const result: string[] = [];
  const startDate = new Date(start);
  const endDate = new Date(end);
  let current = new Date(startDate);
  while (current <= endDate) {
    // formatTime 需要秒级时间戳
    result.push(formatTime(Math.floor(current.getTime() / 1000),'yyyy-MM-dd'));
    current.setDate(current.getDate() + 1);
  }
  return result;
};
